home *** CD-ROM | disk | FTP | other *** search
/ MIDICraft's MIDINET CD-ROM / MIDICraft's MIDINET CD-ROM.iso / DOSUTILS / MIDISORT / MIDIIO.CPP next >
Encoding:
C/C++ Source or Header  |  1997-03-11  |  47.5 KB  |  2,446 lines

  1. // midiio.cpp written by Günter Nagler 1995 (gnagler@ihm.tu-graz.ac.at)
  2. #include "midiio.hpp"
  3. #include <assert.h>
  4. #ifdef __MSDOS__
  5. #include <mem.h>
  6. #endif
  7. #include <string.h>
  8. #include <stdlib.h>
  9.  
  10. static char* copyright = "midiio v1.7 (c) 1995 by Günter Nagler (" __DATE__ ")";
  11.  
  12. int compress = 1;
  13.  
  14. // common sysex events
  15. unsigned char sysex_gmreset[] = { 0xF0, 0x05, 0x7E, 0x7F, 0x09, 0x01, 0xF7 };
  16. unsigned char sysex_gsreset[] = { 0xF0, 0x0A, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7 };
  17. unsigned char sysex_gsexit[] =  { 0xF0, 0x0A, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x7F, 0x42, 0xF7 };
  18. unsigned char sysex_xgreset[] = { 0xF0, 0x08, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xF7 };
  19.  
  20. static int issysex(unsigned char* sysex, unsigned char* sysdata, int syslen)
  21. {
  22.   if (*sysex == 0xF0)
  23.     sysex++;
  24.   while (syslen > 0)
  25.   {
  26.     if (*sysex != *sysdata)
  27.       return 0;
  28.     syslen--;
  29.     if (*sysex == 0xF7)
  30.       break;
  31.     sysex++;
  32.     sysdata++;
  33.   }
  34.   return (syslen != 0) ? 0 : 1;
  35. }
  36.  
  37. static int sysexlen(unsigned char* sysex)
  38. {
  39. int len = 0;
  40.  
  41.   len = 0;
  42.   while (*sysex != 0xF7)
  43.   {
  44.     sysex++;
  45.     len++;
  46.   }
  47.   return len+1; // incl. F7
  48. }
  49.  
  50. // class MidiRead
  51.  
  52. const char* MidiRead::copyright()
  53. {
  54.   return (const char*)::copyright;
  55. }
  56.  
  57. MidiBuffer::MidiBuffer(const char* filename, FILE* f, char preload)
  58. {
  59.   shouldfreemidibuf_ = 1;
  60.   midiname_ = filename;
  61.   midibuf_ = 0;
  62.   if (f)
  63.   {
  64.     f_ = f;
  65.     shouldclose_ = 0;
  66.   }
  67.   else
  68.   {
  69.     shouldclose_ = 1;
  70.     if (!filename)
  71.       f_ = 0;
  72.     else
  73.       f_ = fopen(filename, READ_BINARY);
  74.   }
  75.   if (f_)
  76.   {
  77.     fseek(f_, 0L, SEEK_END);
  78.     filesize_ = ftell(f_);
  79.     fseek(f_, 0L, SEEK_SET);
  80.   }
  81.   else
  82.     filesize_ = 0;
  83.  
  84.   if (filesize_ > 0 && preload
  85. #ifdef __MSDOS__
  86.     && filesize_ <= 0x7fff
  87. #endif
  88.   )
  89.   {
  90.     midibuf_ = (unsigned char*)malloc((int)filesize_);
  91.     if (midibuf_)
  92.     {
  93.       if (fread(midibuf_, (int)filesize_, 1, f_) != 1)
  94.       {
  95.     free(midibuf_);
  96.     midibuf_ = 0;
  97.       }
  98.     }
  99.   }
  100. }
  101.  
  102. MidiBuffer::MidiBuffer(unsigned char* mididata, long mididatalen, char shouldfree)
  103. {
  104.   midiname_ = 0;
  105.   f_ = 0;
  106.   shouldclose_ = 0;
  107.   midibuf_ = mididata;
  108.   if (midibuf_)
  109.     filesize_ = mididatalen;
  110.   else
  111.     filesize_ = 0;
  112.   shouldfreemidibuf_ = shouldfree;
  113. }
  114.  
  115. long MidiBuffer::midilength()
  116. {
  117.   return filesize_;
  118. }
  119.  
  120. MidiBuffer::~MidiBuffer()
  121. {
  122.   if (f_ && shouldclose_)
  123.   {
  124.     fclose(f_);
  125.     f_ = 0;
  126.   }
  127.   if (midibuf_)
  128.   {
  129.     if (shouldfreemidibuf_)
  130.       free(midibuf_);
  131.     midibuf_ = 0;
  132.   }
  133. }
  134.  
  135. int MidiBuffer::need(long pos, unsigned char* buf, int bufsize)
  136. {
  137.   if (!buf || bufsize <= 0 || pos >= filesize_)
  138.     return 0;
  139.   if (midibuf_)
  140.   {
  141.     if (filesize_ - pos < bufsize)
  142.       bufsize = (int)(filesize_-pos);
  143.     memcpy(buf, midibuf_+(int)pos, bufsize);
  144.     return bufsize;
  145.   }
  146.   if (f_)
  147.   {
  148.     fseek(f_, pos, SEEK_SET);
  149.     int l = fread(buf, 1, bufsize, f_);
  150.     if (l > 0)
  151.       return l;
  152.   }
  153.   return 0;
  154. }
  155.  
  156. MidiRead::MidiRead(const char* filename, FILE* f, char preload) : MidiBuffer(filename, f, preload)
  157. {
  158.   buflen_ = 0;
  159.   bufpos_ = 0;
  160.   curpos_ = 0;
  161.   pos_ = 0;
  162.   curchannel_ = NOCHANNEL;
  163.   curunit_ = 0;
  164.   options_ = 0;
  165.   curms_ = currest_ = 0;
  166.   microsecperbeat_ = timediv_ = 0;
  167.  
  168.   version_ = tracks_ = unitsperbeat_ = trackno_ = 0;
  169.   tracklen_ = 0;
  170.   skiptrack_ = 0;
  171. }
  172.  
  173. MidiRead::~MidiRead()
  174. {
  175. }
  176.  
  177. long MidiRead::seekmidihead()
  178. {
  179. long pos = 0;
  180. unsigned char* data;
  181. int n;
  182.  
  183.   while (pos < midilength())
  184.   {
  185.     seek(pos);
  186.     n = sizeof(buf_);
  187.     if (n > midilength()-pos)
  188.       n = (int)(midilength()-pos);
  189.     data = need(n);
  190.     if (data)
  191.     {
  192.       int len = n;
  193.       unsigned char* c = data;
  194.       while (len >= 4)
  195.       {
  196.     if (*c == 'M' && c[1] == 'T' && c[2] == 'h' && c[3] == 'd')
  197.     {
  198.       seek(pos);
  199.       return pos;
  200.     }
  201.     len--;
  202.     c++;
  203.     pos++;
  204.       }
  205.       if (midilength() - pos < 4)
  206.     break;
  207.     }
  208.     else
  209.       break;
  210.   }
  211.   seek(0);
  212.   return -1;
  213. }
  214.  
  215. int MidiRead::runhead()
  216. {
  217.   if (seekmidihead() < 0 || getlong() != MThd)
  218.   {
  219.     error("missing midi header MThd");
  220.     return 0;
  221.   }
  222.  
  223.   if (getlong() == 6)
  224.   {
  225.     version_ = getword();
  226.     if (version_ < 0 || version_ > 2)
  227.     {
  228.       error("invalid midi version");
  229.       return 0;
  230.     }
  231.     tracks_ = getword();
  232.     unitsperbeat_ = getword();
  233.     timediv_ = (1000L * unitsperbeat_);
  234.     microsecperbeat_ = 500000L;  // default tempo = 120 beats/min
  235.     head(version_, tracks_, unitsperbeat_);
  236.   }
  237.   else
  238.   {
  239.     error("illegal midi header");
  240.     return 0;
  241.   }
  242.   return 1;
  243. }
  244.  
  245. int MidiRead::run()
  246. {
  247.   pos_ = curpos_;
  248.   if (!runhead())
  249.     return 0;
  250.   pos_ = curpos_;
  251.   for (trackno_ = 1; trackno_ <= tracks_; trackno_++)
  252.     if (!runtrack(trackno_))
  253.       return 0;
  254.   if (curpos_ >= filesize_)
  255.     percent(percent_ = 100);
  256.   endmidi();
  257.   return 1;
  258. }
  259.  
  260. int MidiRead::runevent(long trackend)
  261. {
  262. int midicode;
  263.  
  264.   pos_ = curpos_;
  265.  
  266.   unsigned char *c = need(1);
  267.   if (!c || c[0] >= 0x80 || lastcode_ < 0)
  268.     midicode = getbyte();
  269.   else
  270.     midicode = lastcode_;
  271.  
  272.   if (midicode < 0)
  273.     return 0;
  274.  
  275.   switch(midicode)
  276.   {
  277.   case 0xf0: // sysex
  278.     {
  279.       int syslen = scansysevent(trackend - curpos_);
  280.       if (!syslen)
  281.       {
  282.     error("end of sysex not found or sysex too large");
  283.     return 0;
  284.       }
  285.       unsigned char* sysdata = get(syslen);
  286.       if ((options_ & OPTION_NOSYSEVENTS) == 0)
  287.       {
  288.     if (issysex(sysex_gmreset, sysdata, syslen))
  289.       gmreset();
  290.     else if (issysex(sysex_gsreset, sysdata, syslen))
  291.       gsreset();
  292.     else if (issysex(sysex_gsexit, sysdata, syslen))
  293.       gsexit();
  294.     else if (issysex(sysex_xgreset, sysdata, syslen))
  295.       xgreset();
  296.     else
  297.       sysex(syslen, sysdata);
  298.       }
  299.       else if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  300.     sysex(syslen, sysdata);
  301.       else
  302.     event(0xf0, syslen, sysdata);
  303.     }
  304.     break;
  305.   case 0xf2:
  306.   {
  307.     c = get(2); if (!c) return 0;
  308.     if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  309.       songpos((unsigned(c[1]) << 7) + unsigned(c[0]));
  310.     else
  311.       event(0xf2, 2, c);
  312.     break;
  313.   }
  314.   case 0xf3:
  315.     c = get(1); if (!c) return 0;
  316.     if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  317.       songselect(*c);
  318.     else
  319.       event(0xf3, 1, c);
  320.     break;
  321.   case 0xf6:
  322.     if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  323.       tunerequest();
  324.     else
  325.       event(0xf6);
  326.     break;
  327.   case 0xf8:
  328.     if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  329.       timingclock();
  330.     else
  331.       event(0xf8);
  332.     break;
  333.   case 0xfa:
  334.     if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  335.       start();
  336.     else
  337.       event(0xfa);
  338.     break;
  339.   case 0xfb:
  340.     if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  341.       cont();
  342.     else
  343.       event(0xfb);
  344.     break;
  345.   case 0xfc:
  346.     if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  347.       stop();
  348.     else
  349.       event(0xfc);
  350.     break;
  351.   case 0xfe:
  352.     if ((options_ & OPTION_NOREALTIMEEVENTS) == 0)
  353.       activesense();
  354.     else
  355.       event(0xfe);
  356.     break;
  357.   case 0xff:
  358.     {
  359.     int c;
  360.     unsigned long endpos;
  361.     int len;
  362.  
  363.       c = getbyte();
  364.       len = (int)getdelta();
  365.       endpos = curpos_ + len;
  366.       if (options_ & OPTION_NOREALTIMEEVENTS)
  367.       {
  368.     len += curdeltalen_ + 1;
  369.     seek(curpos_ - curdeltalen_ - 1);
  370.     event(0xff, len, get(len));
  371.       }
  372.       else if (options_ & OPTION_NOMETAEVENTS)
  373.     meta(c, len, get(len));
  374.       else
  375.     switch(c)
  376.     {
  377.     case 0:
  378.       if (len == 2)
  379.         seqnumber(getword());
  380.       else
  381.         meta(c, len, get(len));
  382.       break;
  383.     case meta_text:
  384.       text(c, len, "text", get(len)); break;
  385.     case meta_copyright:
  386.       text(c, len, "copyright", get(len));  break;
  387.     case meta_trackname:
  388.       text(c, len, "trackname", get(len)); break;
  389.     case meta_instrument:
  390.       text(c, len, "instrument", get(len)); break;
  391.     case meta_lyric:
  392.       text(c, len, "lyric", get(len)); break;
  393.     case meta_marker:
  394.       text(c, len, "marker", get(len)); break;
  395.     case meta_cuepoint:
  396.       text(c, len, "cuepoint", get(len)); break;
  397.     case 8:
  398.     case 9:
  399.     case 10:
  400.     case 11:
  401.     case 12:
  402.     case 13:
  403.     case 14:
  404.     case 15:
  405.       text(c, len, 0, get(len)); break;
  406.     case 0x20:
  407.       if (len == 1)
  408.         prefixchannel(getbyte());
  409.       else
  410.         meta(c, len, get(len));
  411.       break;
  412.     case 0x21:
  413.       if (len == 1)
  414.         prefixport(getbyte());
  415.       else
  416.         meta(c, len, get(len));
  417.       break;
  418.     case 0x2F:
  419.       end();
  420.       break;
  421.     case 0x51:
  422.       tempo(microsecperbeat_ = gettri());
  423.       break;
  424.     case 0x54:
  425.       if (len == 5)
  426.       {
  427.       unsigned char *s = get(len);
  428.  
  429.         smpteofs(s[0], s[1], s[2], s[3], s[4]);
  430.       }
  431.       else
  432.         meta(c, len, get(len));
  433.       break;
  434.     case 0x58:
  435.       if (len == 4)
  436.       {
  437.       int nom, unitsperbeat, notes32perbeat, log2denom;
  438.  
  439.         nom = getbyte();
  440.         log2denom = getbyte();
  441.  
  442.         unitsperbeat = getbyte();
  443.         notes32perbeat = getbyte();
  444.         tact(nom, 1 << log2denom, unitsperbeat, notes32perbeat);
  445.       }
  446.       else
  447.         meta(c, len, get(len));
  448.       break;
  449.     case 0x59:
  450.       if (len == 2)
  451.       {
  452.       signed char s[2];
  453.  
  454.         s[0] = (signed char)getbyte(); // sf
  455.         s[1] = (signed char)getbyte(); // mi
  456.         if (s[0] >= -7 && s[0] <= +7 && s[1] >= 0 && s[1] <= 1)
  457.           key(s[0], s[1]);
  458.         else
  459.           meta(c, len, (unsigned char*)s);
  460.       }
  461.       else
  462.         meta(c, len, get(len));
  463.       break;
  464.     default:
  465.       meta(c, len, get(len));
  466.       break;
  467.     }
  468.       seek(endpos);
  469.     }
  470.     break;
  471.   default:
  472.     {
  473.       if (midicode < 0)
  474.     return 0;
  475.       if (midicode < 0x80)
  476.       {
  477.       char msg[30];
  478.  
  479.     sprintf(msg, "illegal midi command %02X", midicode);
  480.     error(msg);
  481.     return 0;
  482.       }
  483.       int channel = midicode & 0x0F;
  484.       int cmd = midicode & 0xF0;
  485.  
  486.       switch(cmd)
  487.       {
  488.       case 0x80:
  489.       case 0x90:
  490.     {
  491.     unsigned char* c;
  492.  
  493.       lastcode_ = midicode;
  494.       c = get(2); if (!c) return 0;
  495.       if (options_ & OPTION_NONOTEEVENTS)
  496.         event(midicode, 2, c);
  497.       else
  498.       {
  499.         if (cmd == 0x80 || c[1] == 0)
  500.           noteoff(channel, c[0], c[1]);
  501.         else
  502.           noteon(channel, c[0], c[1]);
  503.       }
  504.     }
  505.     break;
  506.       case 0xA0:
  507.     {
  508.     unsigned char* p = get(2); if (!p) return 0;
  509.  
  510.       lastcode_ = midicode;
  511.  
  512.       if (options_ & OPTION_NOPOLYEVENTS)
  513.         event(midicode, 2, p);
  514.       else
  515.       {
  516.         polyaftertouch(channel, p[0], p[1]);
  517.       }
  518.     }
  519.     break;
  520.       case 0xB0:
  521.     {
  522.     unsigned char* p = get(2); if (!p) return 0;
  523.  
  524.       if (p[1] >= 0x80)
  525.         warning("invalid control value used");
  526.  
  527.       lastcode_ = midicode;
  528.       if (options_ & OPTION_NOCONTROLEVENTS)
  529.         event(midicode, 2, p);
  530.       else if (options_ & OPTION_NOCONTROLS)
  531.         control(channel, p[0], p[1]);
  532.       else
  533.         switch(p[0])
  534.         {
  535.         case ctrl_highbank: highbank(channel, p[1]); break;
  536.         case ctrl_wheel: wheel(channel, p[1]); break;
  537.         case ctrl_breath: breath(channel, p[1]); break;
  538.         case ctrl_foot: foot(channel, p[1]); break;
  539.         case ctrl_portamentotime: portamentotime(channel, p[1]); break;
  540.         case ctrl_data: data(channel, p[1]); break;
  541.         case ctrl_volume: volume(channel, p[1]); break;
  542.         case ctrl_balance: balance(channel, p[1]); break;
  543.         case ctrl_expression: expression(channel, p[1]); break;
  544.         case ctrl_lowbank: lowbank(channel, p[1]); break;
  545.         case ctrl_hold: hold(channel, p[1]); break;
  546.         case ctrl_reverb: reverb(channel, p[1]); break;
  547.         case ctrl_chorus: chorus(channel, p[1]); break;
  548.         case ctrl_datainc: datainc(channel, p[1]); break;
  549.         case ctrl_datadec: datadec(channel, p[1]); break;
  550.         case ctrl_lowrpn: lowrpn(channel, p[1]); break;
  551.         case ctrl_highrpn:
  552.           {
  553.           unsigned char *c = need(8);
  554.  
  555.         if (c &&
  556.           c[0] == 0 && c[1] == midicode && c[2] == ctrl_lowrpn && c[3] == 0 &&
  557.           c[4] == 0 && c[5] == midicode && c[6] == ctrl_data)
  558.         {
  559.           c = get(8);
  560.           pitchbendrange(channel, c[7]);
  561.         }
  562.         else
  563.           highrpn(channel, p[1]);
  564.         break;
  565.           }
  566.         default:
  567.           control(channel, p[0], p[1]);
  568.           break;
  569.         }
  570.       break;
  571.     }
  572.  
  573.       case 0xC0:
  574.     {
  575.     unsigned char* p = get(1); if (!p) return 0;
  576.  
  577.       if (*p >= 0x80)
  578.         warning("invalid program used");
  579.       lastcode_ = midicode;
  580.       if (options_ & OPTION_NOPROGRAMEVENTS)
  581.         event(midicode, 1, p);
  582.       else
  583.         program(channel, p[0]);
  584.     }
  585.     break;
  586.       case 0xD0:
  587.     {
  588.     unsigned char* p = get(1); if (!p) return 0;
  589.  
  590.       lastcode_ = midicode;
  591.       if (options_ & OPTION_NOAFTERTOUCHEVENTS)
  592.         event(midicode, 1, p);
  593.       else
  594.         aftertouch(channel, p[0]);
  595.     }
  596.     break;
  597.       case 0xE0:
  598.     {
  599.     unsigned char* p = get(2); if (!p) return 0;
  600.     unsigned val = unsigned(p[0]) + (unsigned(p[1]) << 7);
  601.  
  602.       lastcode_ = midicode;
  603.       if (options_ & OPTION_NOPITCHBENDEVENTS)
  604.         event(midicode, 2, p);
  605.       else
  606.         pitchbend(channel, val);
  607.     }
  608.     break;
  609.       default:
  610.     {
  611.     char msg[30];
  612.  
  613.       sprintf(msg, "unexpected command byte %02X", midicode);
  614.       error(msg);
  615.       return 0;
  616.     }
  617.       }
  618.     }
  619.     break;
  620.   }
  621.   return (int)(curpos_ - pos_);
  622. }
  623.  
  624. int MidiRead::runtrack(int trackno)
  625. {
  626. unsigned long trackpos = curpos_, trackend;
  627.  
  628.   skiptrack_ = 0;
  629.   curunit_ = 0;
  630.   curms_ = currest_ = 0;
  631.   lastcode_ = -1;
  632.   pos_ = curpos_;
  633.  
  634.   if (getlong() != MTrk)
  635.   {
  636.     error("missing midi track MTrk");
  637.     return 0;
  638.   }
  639.   tracklen_ = getlong();
  640.   track(trackno, tracklen_, curchannel_ = scanchannel(tracklen_));
  641.   trackpos = curpos_;
  642.   trackend = trackpos + tracklen_;
  643.   lastcode_ = -1;
  644.   if ((options_ & OPTION_NOEVENTS) == 0)
  645.   while (!skiptrack_ && curpos_ < trackpos + tracklen_)
  646.   {
  647.     int newpercent = (int)((curpos_ * 100) / filesize_);
  648.     if (newpercent != percent_)
  649.       percent(percent_ = newpercent);
  650.  
  651.     unsigned long delta = getdelta();
  652.     if ( delta >= NOTREALISTIC_PAUSE )
  653.       warning("Unrealistic large pause found");
  654.     time(delta);
  655.     curunit_ += delta;
  656.  
  657.     calctime(delta, curms_, currest_);
  658.  
  659.     if (runevent(trackend) <= 0)
  660.     {
  661.       skiptrack_ = 0;
  662.       return 0;
  663.     }
  664.   }
  665.   skiptrack_ = 0;
  666.   seek(trackend);
  667.   pos_ = curpos_;
  668.   endtrack(trackno);
  669.   return 1;
  670. }
  671.  
  672. void MidiRead::setchannel(int channel)
  673. {
  674.   assert(channel >= -1 && channel <= 15);
  675.   curchannel_ = channel;
  676. }
  677.  
  678. int MidiRead::scansysevent(unsigned long maxlen)
  679. {
  680. int n = sizeof(buf_);
  681. unsigned char* c, *p;
  682. long savepos = curpos_;
  683. int len;
  684.  
  685.   if (maxlen < n)
  686.     n = (int)maxlen;
  687.   c = need(n);
  688.   if (!c)
  689.   {
  690.     n = buflen_;
  691.     c = need(n);
  692.     if (!c)
  693.       return 0;
  694.   }
  695.  
  696.   if (c[0] < 0x80)
  697.   {
  698.     // short sysex 0..127 bytes
  699.     len = c[0];
  700.     if (n >= len+1)
  701.     {
  702.       if (c[len] == 0xF7)
  703.     return len+1;
  704.     }
  705.   }
  706.   else if (n >= 2 && c[1] < 0x80)
  707.   {
  708.     // 128..16383 bytes
  709.     int len = (int(c[0] & 0x7f) << 7) + c[1];
  710.     if (n >= len + 2)
  711.     {
  712.       if (c[len+1] == 0xF7)
  713.     return len+2;
  714.     }
  715.   }
  716.   // sysex events without length information?
  717.   p = (unsigned char*)memchr(c, 0xF7, n);
  718.   if (p)
  719.     return (int)(p - c + 1);
  720.   seek(savepos);
  721.   return 0;
  722. }
  723.  
  724. int MidiRead::scanchannel(unsigned long maxlen)
  725. {
  726. unsigned n = buflen_;
  727. unsigned char* c;
  728. int firstchannel = NOCHANNEL;
  729. int channel, code;
  730. long savepos = curpos_, endpos;
  731. int lastcode = -1;
  732.  
  733.   if (maxlen < n)
  734.     n = (unsigned)maxlen;
  735.   c = need(n);
  736.   if (!c)
  737.     return -1;
  738.  
  739.   endpos = curpos_ + n;
  740.   while (curpos_ < endpos)
  741.   {
  742.     channel = NOCHANNEL;
  743.     getdelta();
  744.     c = need(1);
  745.     if (!c || *c >= 0x80 || lastcode < 0)
  746.       code = getbyte();
  747.     else
  748.       code = lastcode;
  749.     switch(code & 0xF0)
  750.     {
  751.     case 0xF0:
  752.       switch(code)
  753.       {
  754.       case 0xFF:
  755.     getbyte();
  756.     get((int)getdelta());
  757.     break;
  758.       case 0xf0: // sysex
  759.     {
  760.       int len = scansysevent(endpos-curpos_);
  761.       if (!get(len))
  762.         goto endscan;
  763.     }
  764.     break;
  765.       case 0xf2: get(2); break;
  766.       case 0xf3: getbyte(); break;
  767.       case 0xf6:
  768.       case 0xf8:
  769.       case 0xfa:
  770.       case 0xfb:
  771.       case 0xfc:
  772.       case 0xfe:
  773.     break;
  774.       default:
  775.     goto endscan;
  776.       }
  777.       break;
  778.     case 0x80:
  779.     case 0x90:
  780.     case 0xA0:
  781.     case 0xB0:
  782.     case 0xE0:
  783.       channel = code & 15;
  784.       get(2);
  785.       break;
  786.     case 0xC0:
  787.     case 0xD0:
  788.       channel = code & 15;
  789.       getbyte();
  790.       break;
  791.     default:
  792.       goto endscan;
  793.     }
  794.     if (code < 0xf0)
  795.       lastcode = code;
  796.     if (channel >= 0)
  797.     {
  798.       if (firstchannel < 0)
  799.     firstchannel = channel;
  800.       else if (channel != firstchannel)
  801.       {
  802.     firstchannel = MULTICHANNEL;
  803.     break;
  804.       }
  805.     }
  806.   }
  807. endscan:
  808.   seek(savepos);
  809.   return firstchannel;
  810. }
  811.  
  812. int MidiRead::getbyte()
  813. {
  814. unsigned char* c = get(1);
  815.  
  816.   if (c)
  817.     return *c;
  818.   return -1;
  819. }
  820.  
  821. unsigned MidiRead::getword()
  822. {
  823. unsigned char* c = get(2);
  824. unsigned n = 0;
  825.  
  826.   if (c)
  827.   {
  828.     n = *c++;
  829.     n = (n << 8) + *c++;
  830.   }
  831.   return n;
  832. }
  833.  
  834. unsigned long MidiRead::gettri()
  835. {
  836. unsigned char* c = get(3);
  837. unsigned long n = 0;
  838.  
  839.   if (c)
  840.   {
  841.     n = *c++;
  842.     n = (n << 8) + *c++;
  843.     n = (n << 8) + *c++;
  844.   }
  845.   return n;
  846. }
  847.  
  848. unsigned long MidiRead::getlong()
  849. {
  850. unsigned char* c = get(4);
  851. unsigned long n = 0;
  852.  
  853.   if (c)
  854.   {
  855.     n = *c++;
  856.     n = (n << 8) + *c++;
  857.     n = (n << 8) + *c++;
  858.     n = (n << 8) + *c++;
  859.   }
  860.   return n;
  861. }
  862.  
  863. unsigned long MidiRead::getdelta()
  864. {
  865. unsigned long n = 0;
  866. int i = 0, c;
  867.  
  868.   curdeltalen_ = 0;
  869.   for (i = 0; i < 4; i++)
  870.   {
  871.     c = getbyte();
  872.     if (c < 0)
  873.     {
  874.       error("unexpected end of file");
  875.       return 0;
  876.     }
  877.     curdeltalen_++;
  878.     n = (n << 7) + (c & 0x7f);
  879.     if ((c & 0x80) == 0)
  880.       break;
  881.   }
  882.   return n;
  883. }
  884.  
  885. unsigned char* MidiRead::need(int n)
  886. {
  887.   assert(n >= 0);
  888.   if (n == 0)
  889.     return 0;
  890.   if (n > buflen_)
  891.   {
  892.     if (n > sizeof(buf_))
  893.       return 0;
  894.     buflen_ = MidiBuffer::need(curpos_, buf_, sizeof(buf_));
  895.     bufpos_ = 0;
  896.   }
  897.   if (n <= buflen_)
  898.     return buf_ + bufpos_;
  899.   return 0;
  900. }
  901.  
  902. unsigned char* MidiRead::get(int n)
  903. {
  904. unsigned char* s;
  905.  
  906.   s = need(n);
  907.   if (s)
  908.   {
  909.     buflen_ -= n;
  910.     bufpos_ += n;
  911.     curpos_ += n;
  912.   }
  913.   else if (n > sizeof(buf_))
  914.    warning("midi event larger than internal bufsize ignored");
  915.   else if (n > 0)
  916.   {
  917.     error("unexpected end of file");
  918.     skiptrack_ = 1;
  919.   }
  920.   return s;
  921. }
  922.  
  923. void MidiRead::seek(long pos)
  924. {
  925.   if (pos == curpos_ || pos < 0)
  926.     return;
  927.   if (pos >= curpos_ - bufpos_ && pos < curpos_ - bufpos_ + buflen_)
  928.   {
  929.   int n = (int)(pos - curpos_ + bufpos_);
  930.  
  931.     if (n < bufpos_)
  932.     {
  933.       buflen_ += bufpos_ - n;
  934.       bufpos_ -= bufpos_ - n;
  935.     }
  936.     else
  937.     {
  938.       buflen_ -= n - bufpos_;
  939.       bufpos_ += n - bufpos_;
  940.     }
  941.     curpos_ = pos;
  942.   }
  943.   else
  944.   {
  945.     curpos_ = pos;
  946.     bufpos_ = buflen_ = 0;
  947.   }
  948. }
  949.  
  950. unsigned long MidiRead::microsec(unsigned long units, unsigned long msperbeat)
  951. {
  952.   assert(unitsperbeat_ != 0);   // call runhead() or run() first!
  953.  
  954.   if (units > msperbeat)
  955.     return (units / unitsperbeat_) * msperbeat;
  956.   else
  957.     return units * (msperbeat / unitsperbeat_);
  958. }
  959.  
  960.  
  961. long MidiRead::units(unsigned long microsec, unsigned long msperbeat)
  962. {
  963.   assert(unitsperbeat_ != 0);   // call runhead() or run() first!
  964.   assert(msperbeat > 0);  // invalid tempo!
  965.   int unitsperbeat = unitsperbeat_;
  966.   while ((msperbeat & 1) == 0)
  967.   {
  968.     if ((unitsperbeat & 1) == 0)
  969.       unitsperbeat >>= 1;
  970.     else if ((microsec & 1) == 0)
  971.       microsec >>= 1;
  972.     else
  973.       break;
  974.     msperbeat >>= 1;
  975.   }
  976.   if (microsec >= 0x10000L)
  977.     return (microsec / msperbeat) * unitsperbeat;
  978.   else
  979.     return (microsec * unitsperbeat) / msperbeat;
  980. }
  981.  
  982.  
  983. static char* GMProg[128] =
  984. {
  985.   "Piano", "BritePiano", "HammerPiano", "HonkeyTonk", "NewTines", "DigiPiano", "Harpsicord", "Clav",
  986.   "Celesta", "Glocken", "MusicBox", "Vibes", "Marimba", "Xylophon", "Tubular", "Santur",
  987.   "FullOrgan", "PercOrgan", "BX-3Organ", "ChurchPipe", "Positive", "Musette", "Harmonica", "Tango",
  988.   "ClassicGtr", "A.Guitar", "JazzGuitar", "CleanGtr", "MuteGuitar", "OverDrive", "DistGuitar", "RockMonics",
  989.   "JazzBass", "DeepBass", "PickBass", "FretLess", "SlapBass1", "SlapBass2", "SynthBass1", "SynthBass2",
  990.   "Violin", "Viola", "Cello", "ContraBass", "TremoloStr", "Pizzicato", "Harp", "Timpani",
  991.   "Marcato", "SlowString", "AnalogPad", "StringPad", "Choir", "DooVoice", "Voices", "OrchHit",
  992.   "Trumpet", "Trombone", "Tuba", "MutedTrumpet", "FrenchHorn", "Brass", "SynBrass1", "SynBrass2",
  993.   "SopranoSax", "AltoSax", "TenorSax", "BariSax", "SweetOboe", "EnglishHorn", "BasoonOboe", "Clarinet",
  994.   "Piccolo", "Flute", "Recorder", "PanFlute", "Bottle", "Shakuhachi","Whistle", "Ocarina",
  995.   "SquareWave", "SawWave", "SynCalinope", "SynChiff", "Charang", "AirChorus", "Rezzo4ths", "Bass&Lead",
  996.   "Fantasia", "WarmPad", "PolyPad", "GhostPad", "BowedGlas", "MetalPad", "HaloPad", "Sweep",
  997.   "IceRain", "SoundTrack", "Crystal", "Atmosphere", "Brightness", "Goblin", "EchoDrop", "StarTheme",
  998.   "Sitar", "Banjo", "Shamisen", "Koto", "Kalimba","Scotland","Fiddle", "Shanai",
  999.   "MetalBell", "Agogo", "SteelDrums", "Woodblock", "Taiko", "Tom", "SynthTom", "RevCymbal",
  1000.   "FretNoise", "NoiseChiff", "Seashore", "Birds", "Telephone", "Helicopter", "Stadium!!", "GunShot"
  1001. };
  1002.  
  1003. const char* MidiRead::notename(unsigned char note)
  1004. {
  1005. static char name[5];
  1006. char* s = name;
  1007.  
  1008.   switch(note % 12)
  1009.   {
  1010.   case 0: *s++ = 'c'; break;
  1011.   case 1: *s++ = 'c'; *s++ = '#'; break;
  1012.   case 2: *s++ = 'd'; break;
  1013.   case 3: *s++ = 'd'; *s++ = '#'; break;
  1014.   case 4: *s++ = 'e'; break;
  1015.   case 5: *s++ = 'f'; break;
  1016.   case 6: *s++ = 'f'; *s++ = '#'; break;
  1017.   case 7: *s++ = 'g'; break;
  1018.   case 8: *s++ = 'g'; *s++ = '#'; break;
  1019.   case 9: *s++ = 'a'; break;
  1020.   case 10: *s++ = 'a'; *s++ = '#'; break;
  1021.   case 11: *s++ = 'b'; break; // former 'h': German language only
  1022.   }
  1023.  
  1024.   sprintf(s, "%d", (note / 12)-1);  // octave  (assuming Piano C4 is 60)
  1025.   return (const char*) name;
  1026. }
  1027.  
  1028.  
  1029. const char* MidiRead::progname(int n, int channel)
  1030. {
  1031. static char defname[10] = "";
  1032.  
  1033.   if (channel == 9) // drum programs
  1034.   {
  1035.     switch(n)
  1036.     {
  1037.     case 0:    return "Dr1";
  1038.     case 0x10: return "Dr2";
  1039.     case 0x19: return "Dr3";
  1040.     case 0x20: return "Dr4";
  1041.     case 0x28: return "Dr5";
  1042.     case 0x40: return "Dr6";
  1043.     case 0x18: return "Dr7";
  1044.     case 0x30: return "Dr8";
  1045.     }
  1046.   }
  1047.   else if (n >= 0 && n <= 127)
  1048.     return GMProg[n];
  1049. def:
  1050.   sprintf(defname, "%d", n);
  1051.   return (const char*)defname;
  1052. }
  1053.  
  1054. void MidiRead::head(unsigned version, unsigned tracks, unsigned unitperbeat)
  1055. {
  1056. }
  1057.  
  1058. void MidiRead::track(int trackno, long length, int channel)
  1059. {
  1060. }
  1061.  
  1062. void MidiRead::endtrack(int trackno)
  1063. {
  1064. }
  1065.  
  1066. void MidiRead::event(int what, int len, unsigned char* data)
  1067. {
  1068. }
  1069.  
  1070. void MidiRead::seqnumber(unsigned int seqno)
  1071. {
  1072. }
  1073.  
  1074. void MidiRead::smpteofs(int hour, int min, int sec, int frame, int fracframe)
  1075. {
  1076. }
  1077.  
  1078. void MidiRead::key(int signature, int isminor)
  1079. {
  1080. }
  1081.  
  1082. void MidiRead::prefixchannel(unsigned char channel)
  1083. {
  1084. }
  1085.  
  1086. void MidiRead::prefixport(unsigned char port)
  1087. {
  1088. }
  1089.  
  1090. void MidiRead::text(int what, int len, char* whattext, unsigned char* txt)
  1091. {
  1092. }
  1093.  
  1094. void MidiRead::meta(int what, int len, unsigned char* data)
  1095. {
  1096. }
  1097.  
  1098. void MidiRead::end()
  1099. {
  1100. }
  1101.  
  1102. void MidiRead::tact(int nom, int denom, int v1, int v2)
  1103. {
  1104. }
  1105.  
  1106. void MidiRead::tempo(unsigned long ticks)
  1107. {
  1108. }
  1109.  
  1110. void MidiRead::program(int channel, int program)
  1111. {
  1112. }
  1113.  
  1114. void MidiRead::control(int channel, int what, int value)
  1115. {
  1116. }
  1117.  
  1118. void MidiRead::highbank(int channel, int val)
  1119. {
  1120.   control(channel, ctrl_highbank, val);
  1121. }
  1122.  
  1123. void MidiRead::wheel(int channel, int val)
  1124. {
  1125.   control(channel, ctrl_wheel, val);
  1126. }
  1127.  
  1128. void MidiRead::breath(int channel, int val)
  1129. {
  1130.   control(channel, ctrl_breath, val);
  1131. }
  1132.  
  1133. void MidiRead::foot(int channel, int val)
  1134. {
  1135.   control(channel, ctrl_foot, val);
  1136. }
  1137.  
  1138. void MidiRead::portamentotime(int channel, int val)
  1139. {
  1140.   control(channel, ctrl_portamentotime, val);
  1141. }
  1142.  
  1143. void MidiRead::data(int channel, int val)
  1144. {
  1145.   control(channel, ctrl_data, val);
  1146. }
  1147.  
  1148. void MidiRead::volume(int channel, int val)
  1149. {
  1150.   control(channel, ctrl_volume, val);
  1151. }
  1152.  
  1153. void MidiRead::balance(int channel, int val)
  1154. {
  1155.   control(channel, ctrl_balance, val);
  1156. }
  1157.  
  1158. void MidiRead::expression(int channel, int val)
  1159. {
  1160.   control(channel, ctrl_expression, val);
  1161. }
  1162.  
  1163. void MidiRead::lowbank(int channel, int val)
  1164. {
  1165.   control(channel, ctrl_lowbank, val);
  1166. }
  1167.  
  1168. void MidiRead::hold(int channel, int val)
  1169. {
  1170.   control(channel, ctrl_hold, val);
  1171. }
  1172.  
  1173. void MidiRead::reverb(int channel, int val)
  1174. {
  1175.   control(channel, ctrl_reverb, val);
  1176. }
  1177.  
  1178. void MidiRead::chorus(int channel, int val)
  1179. {
  1180.   control(channel, ctrl_chorus, val);
  1181. }
  1182.  
  1183. void MidiRead::datainc(int channel, int val)
  1184. {
  1185.   control(channel, ctrl_datainc, val);
  1186. }
  1187.  
  1188. void MidiRead::datadec(int channel, int val)
  1189. {
  1190.   control(channel, ctrl_datadec, val);
  1191. }
  1192.  
  1193. void MidiRead::lowrpn(int channel, int val)
  1194. {
  1195.   control(channel, ctrl_lowrpn, val);
  1196. }
  1197.  
  1198. void MidiRead::highrpn(int channel, int val)
  1199. {
  1200.   control(channel, ctrl_highrpn, val);
  1201. }
  1202.  
  1203. void MidiRead::pitchbendrange(int channel, int halfnotes)
  1204. {
  1205.   highrpn(channel, 0);
  1206.   time(0);
  1207.   lowrpn(channel, 0);
  1208.   time(0);
  1209.   data(channel, halfnotes);
  1210. }
  1211.  
  1212. void MidiRead::noteon(int channel, int note, int vel)
  1213. {
  1214. }
  1215.  
  1216. void MidiRead::noteoff(int channel, int note, int vel)
  1217. {
  1218. }
  1219.  
  1220. void MidiRead::time(unsigned long ticks)
  1221. {
  1222. }
  1223.  
  1224. void MidiRead::pitchbend(int channel, int val)
  1225. {
  1226. }
  1227.  
  1228. void MidiRead::polyaftertouch(int channel, int note, int val)
  1229. {
  1230. }
  1231.  
  1232. void MidiRead::aftertouch(int channel, int val)
  1233. {
  1234. }
  1235.  
  1236. void MidiRead::songpos(unsigned pos)
  1237. {
  1238. }
  1239.  
  1240. void MidiRead::songselect(unsigned char song)
  1241. {
  1242. }
  1243.  
  1244. void MidiRead::tunerequest()
  1245. {
  1246. }
  1247.  
  1248. void MidiRead::timingclock()
  1249. {
  1250. }
  1251.  
  1252. void MidiRead::start()
  1253. {
  1254. }
  1255.  
  1256. void MidiRead::cont()
  1257. {
  1258. }
  1259.  
  1260. void MidiRead::stop()
  1261. {
  1262. }
  1263.  
  1264. void MidiRead::activesense()
  1265. {
  1266. }
  1267.  
  1268. void MidiRead::sysex(int syslen, unsigned char* sysdata)
  1269. {
  1270. }
  1271.  
  1272. void MidiRead::gmreset()
  1273. {
  1274. }
  1275.  
  1276. void MidiRead::gsreset()
  1277. {
  1278. }
  1279.  
  1280. void MidiRead::gsexit()
  1281. {
  1282. }
  1283.  
  1284. void MidiRead::xgreset()
  1285. {
  1286. }
  1287.  
  1288. void MidiRead::endmidi()
  1289. {
  1290. }
  1291.  
  1292. void MidiRead::percent(int perc)
  1293. {
  1294. }
  1295.  
  1296. void MidiRead::error(const char* msg)
  1297. {
  1298.   fprintf(stderr, "error: %s\n", msg);
  1299. }
  1300.  
  1301. void MidiRead::warning(const char* msg)
  1302. {
  1303.   fprintf(stderr, "warning: %s\n", msg);
  1304. }
  1305.  
  1306. // calculate time that is units after current time, assuming current speed and resolution
  1307. void MidiRead::calctime(unsigned long units, unsigned long& nextms, unsigned long& nextrest)
  1308. {
  1309.     nextms = curms_;
  1310.     nextrest = currest_;
  1311.  
  1312.     if (units == 0 || timediv_ == 0)  // cannot calc time (track head not parsed)
  1313.       return;
  1314.     unsigned long vms = microsecperbeat_ / timediv_;
  1315.     unsigned long vrest = microsecperbeat_ % timediv_;
  1316.     while (units-- > 0)
  1317.     {
  1318.       nextms += vms;
  1319.       nextrest += vrest;
  1320.       while (nextrest >= timediv_)
  1321.       {
  1322.     nextms++;
  1323.     nextrest -= timediv_;
  1324.       }
  1325.     }
  1326. }
  1327.  
  1328. // calc unit at ms msrest that is in same speed range as current unit
  1329. unsigned long MidiRead::calcunit(unsigned long ms, unsigned long msrest)
  1330. {
  1331. unsigned long diff, diffrest;
  1332. char ge;
  1333.  
  1334.   if (ms > curms_ || (ms == curms_ && msrest >= currest_))
  1335.   {
  1336.     diff = ms - curms_;
  1337.     if (msrest >= currest_)
  1338.       diffrest = msrest - currest_;
  1339.     else
  1340.     {
  1341.       diffrest = msrest + timediv_ - currest_;
  1342.       diff--;
  1343.     }
  1344.     ge = 1;
  1345.   }
  1346.   else
  1347.   {
  1348.     diff = curms_ - ms;
  1349.     if (currest_ >= msrest)
  1350.       diffrest = currest_ - msrest;
  1351.     else
  1352.     {
  1353.       diffrest = currest_ + timediv_ - msrest;
  1354.       diff--;
  1355.     }
  1356.     ge = 0;
  1357.   }
  1358.   unsigned long units = 0;
  1359.   while (diff > 0 || diffrest >= microsecperbeat_)
  1360.   {
  1361.     if (diff > 0)
  1362.     {
  1363.       diff--;
  1364.       diffrest += timediv_;
  1365.     }
  1366.     if (diffrest >= microsecperbeat_)
  1367.     {
  1368.       units++;
  1369.       diffrest -= microsecperbeat_;
  1370.     }
  1371.   }
  1372.   return ge ? curunit_ + units : curunit_ - units;
  1373. }
  1374.  
  1375. FILE* MidiBuffer::getf()
  1376. {
  1377.   return f_;
  1378. }
  1379.  
  1380. // class MidiWrite
  1381.  
  1382. const char* MidiWrite::copyright()
  1383. {
  1384.   return (const char*)::copyright;
  1385. }
  1386.  
  1387. MidiWrite::MidiWrite(const char* filename)
  1388. {
  1389.   midiname_ = filename;
  1390.   if (midiname_)
  1391.     f_ = fopen(midiname_, WRITE_BINARY);
  1392.   else
  1393.     f_ = 0;
  1394.   trackpos_ = -1;
  1395.   curpos_ = 0;
  1396.   trackchannel_ = -1;
  1397.  
  1398.   bufpos_ = 0;
  1399.   buflen_ = 0;
  1400.   filesize_ = 0;
  1401.   trackcount_ = 0;
  1402.   curunit_ = curdelta_ = 0;
  1403.   lastcode_ = -1;
  1404.   unitsperbeat_ = 0;
  1405. }
  1406.  
  1407. MidiWrite::~MidiWrite()
  1408. {
  1409.   if (trackcount_ > 0)
  1410.   {
  1411.     seek(10);
  1412.     putword(trackcount_);
  1413.   }
  1414.   if (trackpos_ > 0)
  1415.     endtrack();
  1416.   flush();
  1417.   if (f_)
  1418.     fclose(f_);
  1419. }
  1420.  
  1421. void MidiWrite::head(int version, int tracks, unsigned unitperbeat)
  1422. {
  1423.   seek(0);
  1424.   putlong(MThd);
  1425.   putlong(6);
  1426.   putword(version);
  1427.   putword(tracks);  // unknown
  1428.   putword(unitsperbeat_ = unitperbeat);
  1429. }
  1430.  
  1431. void MidiWrite::track()
  1432. {
  1433.   if (trackpos_ > 0)
  1434.     endtrack();
  1435.   endtrack_ = 0;
  1436.   lastcode_ = -1;
  1437.   curunit_ = curdelta_ = 0;
  1438.   seek(trackpos_ = filesize_);
  1439.   putlong(MTrk);
  1440.   putlong(0); // unknown yet
  1441.   trackcount_++;
  1442. }
  1443.  
  1444. int MidiWrite::trackcount()
  1445. {
  1446.   return trackcount_;
  1447. }
  1448.  
  1449. void MidiWrite::endtrack()
  1450. {
  1451.   seek(filesize_);
  1452.   if (!endtrack_)
  1453.      end();
  1454.   if (trackpos_ <= 0)
  1455.     return;
  1456.   seek(trackpos_+4);
  1457.   putlong(filesize_ - trackpos_ - 8);
  1458.   trackpos_ = 0;
  1459. }
  1460.  
  1461. void MidiWrite::event(int what, int len, unsigned char* data)
  1462. {
  1463.   puttime();
  1464.   putcode(what);
  1465.   put(len, data);
  1466. }
  1467.  
  1468. void MidiWrite::prefixchannel(unsigned char channel)
  1469. {
  1470.   meta(0x20, 1, &channel);
  1471. }
  1472.  
  1473. void MidiWrite::prefixport(unsigned char port)
  1474. {
  1475.   meta(0x21, 1, &port);
  1476. }
  1477.  
  1478. void MidiWrite::text(int what, int len, unsigned char* txt)
  1479. {
  1480.   if (len < 0)
  1481.     len = strlen((char*)txt);
  1482.   meta(what, len, txt);
  1483. }
  1484.  
  1485. void MidiWrite::meta(int what, int len, unsigned char* data)
  1486. {
  1487.   puttime();
  1488.   putcode(0xff);
  1489.   putbyte(what);
  1490.   putdelta(len);
  1491.   put(len, data);
  1492. }
  1493.  
  1494. void MidiWrite::end()
  1495. {
  1496.   if (endtrack_)  // don't need end of track event twice
  1497.     return;
  1498.   endtrack_ = 1;
  1499.   meta(0x2f, 0, 0);
  1500. }
  1501.  
  1502. void MidiWrite::tact(int nom, int denom, int v1, int v2)
  1503. {
  1504. int log2denom;
  1505.  
  1506.   switch(denom)
  1507.   {
  1508.   case 1:    log2denom = 0; break;
  1509.   case 2:    log2denom = 1; break;
  1510.   case 4:    log2denom = 2; break;
  1511.   case 8:    log2denom = 3; break;
  1512.   case 16:   log2denom = 4; break;
  1513.   case 32:   log2denom = 5; break;
  1514.   case 64:   log2denom = 6; break;
  1515.   case 128:  log2denom = 7; break;
  1516.   case 256:  log2denom = 8; break;
  1517.   default:
  1518.     log2denom = 2;
  1519.     assert((1 << log2denom) == denom);
  1520.   }
  1521.   puttime();
  1522.   putcode(0xff);
  1523.   putbyte(0x58);
  1524.   putbyte(4);
  1525.   putbyte(nom);
  1526.   putbyte(log2denom);
  1527.   putbyte(v1);
  1528.   putbyte(v2);
  1529. }
  1530.  
  1531. void MidiWrite::seqnumber(unsigned int seqno)
  1532. {
  1533.   puttime();
  1534.   putcode(0xff);
  1535.   putbyte(0x00);
  1536.   putbyte(2);
  1537.   putword(seqno);
  1538. }
  1539.  
  1540. void MidiWrite::smpteofs(int hour, int min, int sec, int frame, int fracframe)
  1541. {
  1542.   puttime();
  1543.   putcode(0xff);
  1544.   putbyte(0x54);
  1545.   putbyte(5);
  1546.   putbyte(hour);
  1547.   putbyte(min);
  1548.   putbyte(sec);
  1549.   putbyte(frame);
  1550.   putbyte(fracframe);
  1551. }
  1552.  
  1553. void MidiWrite::key(int signature, int isminor)
  1554. {
  1555.   puttime();
  1556.   putcode(0xff);
  1557.   putbyte(0x59);
  1558.   putbyte(2);
  1559.   putbyte((signed char)signature);
  1560.   putbyte((signed char)isminor);
  1561. }
  1562.  
  1563. void MidiWrite::tempo(unsigned long ticks)
  1564. {
  1565.   puttime();
  1566.   putcode(0xff);
  1567.   putbyte(0x51);
  1568.   putbyte(3);
  1569.   puttri(ticks);
  1570. }
  1571.  
  1572. void MidiWrite::program(int channel, int prg)
  1573. {
  1574.   assert(channel >= 0 && channel < 16);
  1575.   puttime();
  1576.   putcode(0xC0 + channel);
  1577.   putbyte(prg);
  1578. }
  1579.  
  1580. void MidiWrite::control(int channel, int what, int val)
  1581. {
  1582.   assert(channel >= 0 && channel < 16);
  1583.   puttime();
  1584.   putcode(0xB0 + channel);
  1585.   putbyte(what);
  1586.   putbyte(val);
  1587. }
  1588.  
  1589. void MidiWrite::highbank(int channel, int val)
  1590. {
  1591.   control(channel, ctrl_highbank, val);
  1592. }
  1593.  
  1594. void MidiWrite::wheel(int channel, int val)
  1595. {
  1596.   control(channel, ctrl_wheel, val);
  1597. }
  1598.  
  1599. void MidiWrite::breath(int channel, int val)
  1600. {
  1601.   control(channel, ctrl_breath, val);
  1602. }
  1603.  
  1604. void MidiWrite::foot(int channel, int val)
  1605. {
  1606.   control(channel, ctrl_foot, val);
  1607. }
  1608.  
  1609. void MidiWrite::portamentotime(int channel, int val)
  1610. {
  1611.   control(channel, ctrl_portamentotime, val);
  1612. }
  1613.  
  1614. void MidiWrite::data(int channel, int val)
  1615. {
  1616.   control(channel, ctrl_data, val);
  1617. }
  1618.  
  1619. void MidiWrite::volume(int channel, int val)
  1620. {
  1621.   control(channel, ctrl_volume, val);
  1622. }
  1623.  
  1624. void MidiWrite::balance(int channel, int val)
  1625. {
  1626.   control(channel, ctrl_balance, val);
  1627. }
  1628.  
  1629. void MidiWrite::expression(int channel, int val)
  1630. {
  1631.   control(channel, ctrl_expression, val);
  1632. }
  1633.  
  1634. void MidiWrite::lowbank(int channel, int val)
  1635. {
  1636.   control(channel, ctrl_lowbank, val);
  1637. }
  1638.  
  1639. void MidiWrite::hold(int channel, int val)
  1640. {
  1641.   control(channel, ctrl_hold, val);
  1642. }
  1643.  
  1644. void MidiWrite::reverb(int channel, int val)
  1645. {
  1646.   control(channel, ctrl_reverb, val);
  1647. }
  1648.  
  1649. void MidiWrite::chorus(int channel, int val)
  1650. {
  1651.   control(channel, ctrl_chorus, val);
  1652. }
  1653.  
  1654. void MidiWrite::datainc(int channel, int val)
  1655. {
  1656.   control(channel, ctrl_datainc, val);
  1657. }
  1658.  
  1659. void MidiWrite::datadec(int channel, int val)
  1660. {
  1661.   control(channel, ctrl_datadec, val);
  1662. }
  1663.  
  1664. void MidiWrite::lowrpn(int channel, int val)
  1665. {
  1666.   control(channel, ctrl_lowrpn, val);
  1667. }
  1668.  
  1669. void MidiWrite::highrpn(int channel, int val)
  1670. {
  1671.   control(channel, ctrl_highrpn, val);
  1672. }
  1673.  
  1674. void MidiWrite::noteon(int channel, int note, int vel)
  1675. {
  1676.   assert(channel >= 0 && channel < 16);
  1677.   puttime();
  1678.   putcode(0x90+channel);
  1679.   putbyte(note);
  1680.   putbyte(vel);
  1681. }
  1682.  
  1683. void MidiWrite::noteoff(int channel, int note, int vel)
  1684. {
  1685.   assert(channel >= 0 && channel < 16);
  1686.   puttime();
  1687.   if (vel != 0 || lastcode_ < 0 || (lastcode_ & 0xF0) != 0x90)
  1688.     putcode(0x80+channel);
  1689.   else
  1690.     putcode(0x90+channel);  // vel == 0!
  1691.   putbyte(note);
  1692.   putbyte(vel);
  1693. }
  1694.  
  1695. void MidiWrite::time(unsigned long ticks)
  1696. {
  1697.   if ( ticks >= NOTREALISTIC_PAUSE )
  1698.     warning("generating unrealistic large pause");
  1699.   curdelta_ += ticks;
  1700.   curunit_ += ticks;
  1701. }
  1702.  
  1703. void MidiWrite::cleardelta()
  1704. {
  1705.   curunit_ -= curdelta_;
  1706.   curdelta_ = 0;
  1707. }
  1708.  
  1709. void MidiWrite::pitchbend(int channel, int val)
  1710. {
  1711.   assert(channel >= 0 && channel < 16);
  1712.   puttime();
  1713.   putcode(0xE0 + channel);
  1714.   putbyte(val & 0x7F);
  1715.   putbyte((val >> 7) & 0x7F);
  1716. }
  1717.  
  1718. void MidiWrite::polyaftertouch(int channel, int note, int val)
  1719. {
  1720.   assert(channel >= 0 && channel < 16);
  1721.   puttime();
  1722.   putcode(0xA0 + channel);
  1723.   putbyte(note);
  1724.   putbyte(val);
  1725. }
  1726.  
  1727. void MidiWrite::aftertouch(int channel, int val)
  1728. {
  1729.   assert(channel >= 0 && channel < 16);
  1730.   puttime();
  1731.   putcode(0xD0 + channel);
  1732.   putbyte(val);
  1733. }
  1734.  
  1735. void MidiWrite::songpos(unsigned pos)
  1736. {
  1737.   puttime();
  1738.   putcode(0xF2);
  1739.   putbyte(pos & 0x7F);
  1740.   putbyte((pos >> 7) & 0x7F);
  1741. }
  1742.  
  1743. void MidiWrite::songselect(unsigned char song)
  1744. {
  1745.   puttime();
  1746.   putcode(0xF3);
  1747.   putbyte(song);
  1748. }
  1749.  
  1750. void MidiWrite::tunerequest()
  1751. {
  1752.   puttime();
  1753.   putcode(0xf6);
  1754. }
  1755.  
  1756. void MidiWrite::timingclock()
  1757. {
  1758.   puttime();
  1759.   putcode(0xf8);
  1760. }
  1761.  
  1762. void MidiWrite::start()
  1763. {
  1764.   puttime();
  1765.   putcode(0xfa);
  1766. }
  1767.  
  1768. void MidiWrite::cont()
  1769. {
  1770.   puttime();
  1771.   putcode(0xfb);
  1772. }
  1773.  
  1774. void MidiWrite::stop()
  1775. {
  1776.   puttime();
  1777.   putcode(0xfc);
  1778. }
  1779.  
  1780. void MidiWrite::activesense()
  1781. {
  1782.   puttime();
  1783.   putcode(0xfe);
  1784. }
  1785.  
  1786. void MidiWrite::sysex(int syslen, unsigned char* sysdata)
  1787. {
  1788.   puttime();
  1789.   putcode(0xf0);
  1790.   if (*sysdata == 0xF0)
  1791.   {
  1792.     syslen--;
  1793.     sysdata++;
  1794.   }
  1795.   put(syslen, sysdata);
  1796. }
  1797.  
  1798. void MidiWrite::gmreset()
  1799. {
  1800.   sysex(sysexlen(sysex_gmreset), sysex_gmreset);
  1801. }
  1802.  
  1803. void MidiWrite::xgreset()
  1804. {
  1805.   sysex(sysexlen(sysex_xgreset), sysex_xgreset);
  1806. }
  1807.  
  1808. void MidiWrite::gsreset()
  1809. {
  1810.   sysex(sysexlen(sysex_gsreset), sysex_gsreset);
  1811. }
  1812.  
  1813. void MidiWrite::gsexit()
  1814. {
  1815.   sysex(sysexlen(sysex_gsexit), sysex_gsexit);
  1816. }
  1817.  
  1818. void MidiWrite::pitchbendrange(int channel, int halfnotes)
  1819. {
  1820.   highrpn(channel, 0);
  1821.   lowrpn(channel, 0);
  1822.   data(channel, halfnotes);
  1823. }
  1824.  
  1825. void MidiWrite::putbyte(unsigned char val)
  1826. {
  1827.   put(1, &val);
  1828. }
  1829.  
  1830. void MidiWrite::putcode(unsigned char code)
  1831. {
  1832. int put;
  1833.  
  1834.   assert(code >= 0x80);
  1835.  
  1836.   if (compress)
  1837.     put = !(code == lastcode_ && code <= 0x9f);
  1838.   else
  1839.     put = 1;
  1840.   if (put)
  1841.     putbyte(code);
  1842.   lastcode_ = code;
  1843. }
  1844.  
  1845. static unsigned char c[4];
  1846.  
  1847. void MidiWrite::putword(unsigned val)
  1848. {
  1849.   c[1] = (unsigned char)(val & 0xff); val >>= 8;
  1850.   c[0] = (unsigned char)(val & 0xff);
  1851.   put(2, c);
  1852. }
  1853.  
  1854. void MidiWrite::puttri(unsigned long val)
  1855. {
  1856.   c[2] = (unsigned char)(val & 0xff); val >>= 8;
  1857.   c[1] = (unsigned char)(val & 0xff); val >>= 8;
  1858.   c[0] = (unsigned char)(val & 0xff);
  1859.   put(3, c);
  1860. }
  1861.  
  1862. void MidiWrite::putlong(unsigned long val)
  1863. {
  1864.   c[3] = (unsigned char)(val & 0xff); val >>= 8;
  1865.   c[2] = (unsigned char)(val & 0xff); val >>= 8;
  1866.   c[1] = (unsigned char)(val & 0xff); val >>= 8;
  1867.   c[0] = (unsigned char)(val & 0xff);
  1868.   put(4, c);
  1869. }
  1870.  
  1871. void MidiWrite::putdelta(unsigned long val)
  1872. {
  1873.   int i = 0, j = 3;
  1874.   while (i < 4)
  1875.   {
  1876.     c[j] = val & 0x7F;
  1877.     if (j < 3)
  1878.       c[j] |= 0x80;
  1879.     val >>= 7;
  1880.     i++;
  1881.     if (!val)
  1882.       break;
  1883.     j--;
  1884.   }
  1885.   put(i, c+j);
  1886. }
  1887.  
  1888. void MidiWrite::puttime()
  1889. {
  1890.   putdelta(curdelta_);
  1891.   curdelta_ = 0;
  1892. }
  1893.  
  1894. void MidiWrite::flush()
  1895. {
  1896.   if (buflen_ > 0)
  1897.   {
  1898.     fseek(f_, curpos_ - bufpos_, SEEK_SET);
  1899.     if (fwrite(buf_, buflen_, 1, f_) != 1)
  1900.       error("write error (maybe disk full)");
  1901.     assert(ftell(f_) == curpos_ - bufpos_ + buflen_);
  1902.     bufpos_ = buflen_ = 0;
  1903.   }
  1904. }
  1905.  
  1906. void MidiWrite::put(int len, unsigned char* c)
  1907. {
  1908.   if (len <= 0)
  1909.     return;
  1910.   if (c == 0 || len > sizeof(buf_))
  1911.     return;
  1912.   if (sizeof(buf_) - bufpos_ < len)
  1913.     flush();
  1914.   memcpy(buf_+bufpos_, c, len);
  1915.   bufpos_+=len;
  1916.   if (bufpos_ > buflen_)
  1917.     buflen_ = bufpos_;
  1918.   curpos_+= len;
  1919.   if (curpos_ > filesize_)
  1920.     filesize_ = curpos_;
  1921. }
  1922.  
  1923. void MidiWrite::seek(long pos)
  1924. {
  1925.   assert(pos >= 0 && pos <= filesize_);
  1926.   if (curpos_ == pos)
  1927.     return;
  1928.   if (pos >= curpos_-bufpos_ && pos <= curpos_-bufpos_+buflen_)
  1929.   {
  1930.     bufpos_ = (int)(pos - (curpos_-bufpos_));
  1931.     curpos_ = pos;
  1932.     return;
  1933.   }
  1934.   flush();
  1935.   curpos_ = pos;
  1936. }
  1937.  
  1938. FILE* MidiWrite::getf()
  1939. {
  1940.   return f_;
  1941. }
  1942.  
  1943. void MidiWrite::error(const char* msg)
  1944. {
  1945.   fprintf(stderr, "midi write error: %s\n", msg);
  1946. }
  1947.  
  1948. void MidiWrite::warning(const char* msg)
  1949. {
  1950.   fprintf(stderr, "midi write warning: %s\n", msg);
  1951. }
  1952.  
  1953. int MidiWrite::unitsperquarter()
  1954. {
  1955.   return unitsperbeat_;
  1956. }
  1957.  
  1958. MidiCopy::MidiCopy(const char* filename, FILE* f) : MidiRead(filename, f)
  1959. {
  1960.   dest_ = NULL;
  1961.   for (int c = 0; c < 16; c++)
  1962.     mapchannel_[c] = c;        // no change
  1963. }
  1964.  
  1965. void MidiCopy::head(unsigned version, unsigned tracks, unsigned unitperbeat)
  1966. {
  1967.   if (dest_)
  1968.     dest_->head(version, 0, unitperbeat);
  1969. }
  1970.  
  1971. void MidiCopy::track(int trackno, long length, int channel)
  1972. {
  1973.   if (dest_)
  1974.     dest_->track();
  1975. }
  1976.  
  1977. void MidiCopy::endtrack(int trackno)
  1978. {
  1979.   if (dest_)
  1980.     dest_->endtrack();
  1981. }
  1982.  
  1983. void MidiCopy::event(int what, int len, unsigned char* data)
  1984. {
  1985.   if (dest_)
  1986.     dest_->event(what, len, data);
  1987. }
  1988.  
  1989.  
  1990. void MidiCopy::seqnumber(unsigned int seqno)
  1991. {
  1992.   if (dest_)
  1993.     dest_->seqnumber(seqno);
  1994. }
  1995.  
  1996. void MidiCopy::smpteofs(int hour, int min, int sec, int frame, int fracframe)
  1997. {
  1998.   if (dest_)
  1999.     dest_->smpteofs(hour, min, sec, frame, fracframe);
  2000. }
  2001.  
  2002. void MidiCopy::key(int signature, int isminor)
  2003. {
  2004.   if (dest_)
  2005.     dest_->key(signature, isminor);
  2006. }
  2007.  
  2008. void MidiCopy::prefixchannel(unsigned char channel)
  2009. {
  2010.   if (dest_ && mapchannel_[channel] >= 0)
  2011.     dest_->prefixchannel(mapchannel_[channel]);
  2012. }
  2013.  
  2014. void MidiCopy::prefixport(unsigned char port)
  2015. {
  2016.   if (dest_)
  2017.     dest_->prefixport(port);
  2018. }
  2019.  
  2020. void MidiCopy::text(int what, int len, char* whattext, unsigned char* txt)
  2021. {
  2022.   if (dest_)
  2023.     dest_->text(what, len, txt);
  2024. }
  2025.  
  2026. void MidiCopy::meta(int what, int len, unsigned char* data)
  2027. {
  2028.   if (dest_)
  2029.     dest_->meta(what, len, data);
  2030. }
  2031.  
  2032. void MidiCopy::end()
  2033. {
  2034.   if (dest_)
  2035.     dest_->end();
  2036. }
  2037.  
  2038. void MidiCopy::tact(int nom, int denom, int v1, int v2)
  2039. {
  2040.   if (dest_)
  2041.     dest_->tact(nom, denom, v1,v2);
  2042. }
  2043.  
  2044. void MidiCopy::tempo(unsigned long ticks)
  2045. {
  2046.   if (dest_)
  2047.     dest_->tempo(ticks);
  2048. }
  2049.  
  2050. void MidiCopy::program(int channel, int program)
  2051. {
  2052.   if (dest_ && mapchannel_[channel] >= 0)
  2053.     dest_->program(mapchannel_[channel], program);
  2054. }
  2055.  
  2056. void MidiCopy::control(int channel, int what, int value)
  2057. {
  2058.   if (dest_ && mapchannel_[channel] >= 0)
  2059.     dest_->control(mapchannel_[channel], what, value);
  2060. }
  2061.  
  2062. void MidiCopy::highbank(int channel, int val)
  2063. {
  2064.   if (dest_ && mapchannel_[channel] >= 0)
  2065.     dest_->highbank(mapchannel_[channel], val);
  2066. }
  2067.  
  2068. void MidiCopy::wheel(int channel, int val)
  2069. {
  2070.   if (dest_ && mapchannel_[channel] >= 0)
  2071.     dest_->wheel(mapchannel_[channel], val);
  2072. }
  2073.  
  2074. void MidiCopy::breath(int channel, int val)
  2075. {
  2076.   if (dest_ && mapchannel_[channel] >= 0)
  2077.     dest_->wheel(mapchannel_[channel], val);
  2078. }
  2079.  
  2080. void MidiCopy::foot(int channel, int val)
  2081. {
  2082.   if (dest_ && mapchannel_[channel] >= 0)
  2083.     dest_->foot(mapchannel_[channel], val);
  2084. }
  2085.  
  2086. void MidiCopy::portamentotime(int channel, int val)
  2087. {
  2088.   if (dest_ && mapchannel_[channel] >= 0)
  2089.     dest_->portamentotime(mapchannel_[channel], val);
  2090. }
  2091.  
  2092. void MidiCopy::data(int channel, int val)
  2093. {
  2094.   if (dest_ && mapchannel_[channel] >= 0)
  2095.     dest_->data(mapchannel_[channel], val);
  2096. }
  2097.  
  2098. void MidiCopy::volume(int channel, int val)
  2099. {
  2100.   if (dest_ && mapchannel_[channel] >= 0)
  2101.     dest_->volume(mapchannel_[channel], val);
  2102. }
  2103.  
  2104. void MidiCopy::balance(int channel, int val)
  2105. {
  2106.   if (dest_ && mapchannel_[channel] >= 0)
  2107.     dest_->balance(mapchannel_[channel], val);
  2108. }
  2109.  
  2110. void MidiCopy::expression(int channel, int val)
  2111. {
  2112.   if (dest_ && mapchannel_[channel] >= 0)
  2113.     dest_->expression(mapchannel_[channel], val);
  2114. }
  2115.  
  2116. void MidiCopy::lowbank(int channel, int val)
  2117. {
  2118.   if (dest_ && mapchannel_[channel] >= 0)
  2119.     dest_->lowbank(mapchannel_[channel], val);
  2120. }
  2121.  
  2122. void MidiCopy::hold(int channel, int val)
  2123. {
  2124.   if (dest_ && mapchannel_[channel] >= 0)
  2125.     dest_->hold(mapchannel_[channel], val);
  2126. }
  2127.  
  2128. void MidiCopy::reverb(int channel, int val)
  2129. {
  2130.   if (dest_ && mapchannel_[channel] >= 0)
  2131.     dest_->reverb(mapchannel_[channel], val);
  2132. }
  2133.                       
  2134. void MidiCopy::chorus(int channel, int val)
  2135. {
  2136.   if (dest_ && mapchannel_[channel] >= 0)
  2137.     dest_->chorus(mapchannel_[channel], val);
  2138. }
  2139.  
  2140. void MidiCopy::datainc(int channel, int val)
  2141. {
  2142.   if (dest_ && mapchannel_[channel] >= 0)
  2143.     dest_->datainc(mapchannel_[channel], val);
  2144. }
  2145.  
  2146. void MidiCopy::datadec(int channel, int val)
  2147. {
  2148.   if (dest_ && mapchannel_[channel] >= 0)
  2149.     dest_->datadec(mapchannel_[channel], val);
  2150. }
  2151.  
  2152.  
  2153. void MidiCopy::noteon(int channel, int note, int vel)
  2154. {
  2155.   if (dest_ && mapchannel_[channel] >= 0)
  2156.     dest_->noteon(mapchannel_[channel], note, vel);
  2157. }
  2158.  
  2159. void MidiCopy::noteoff(int channel, int note, int vel)
  2160. {
  2161.   if (dest_ && mapchannel_[channel] >= 0)
  2162.     dest_->noteoff(mapchannel_[channel], note, vel);
  2163. }
  2164.  
  2165. void MidiCopy::time(unsigned long ticks)
  2166. {
  2167.   if (dest_)
  2168.     dest_->time(ticks);
  2169. }
  2170.  
  2171. void MidiCopy::pitchbend(int channel, int val)
  2172. {
  2173.   if (dest_ && mapchannel_[channel] >= 0)
  2174.     dest_->pitchbend(mapchannel_[channel],val);
  2175. }
  2176.  
  2177. void MidiCopy::polyaftertouch(int channel, int note, int val)
  2178. {
  2179.   if (dest_ && mapchannel_[channel] >= 0)
  2180.     dest_->polyaftertouch(mapchannel_[channel], note,  val);
  2181. }
  2182.  
  2183. void MidiCopy::aftertouch(int channel, int val)
  2184. {
  2185.   if (dest_ && mapchannel_[channel] >= 0)
  2186.     dest_->aftertouch(mapchannel_[channel],  val);
  2187. }
  2188.  
  2189. void MidiCopy::songpos(unsigned pos)
  2190. {
  2191.   if (dest_)
  2192.     dest_->songpos(pos);
  2193. }
  2194.  
  2195. void MidiCopy::songselect(unsigned char song)
  2196. {
  2197.   if (dest_)
  2198.     dest_->songselect(song);
  2199. }
  2200.  
  2201. void MidiCopy::tunerequest()
  2202. {
  2203.   if (dest_)
  2204.     dest_->tunerequest();
  2205.  
  2206. }
  2207.  
  2208. void MidiCopy::timingclock()
  2209. {
  2210.   if (dest_)
  2211.      dest_->timingclock();
  2212. }
  2213.  
  2214. void MidiCopy::start()
  2215. {
  2216.   if (dest_)
  2217.      dest_->start();
  2218. }
  2219.  
  2220. void MidiCopy::cont()
  2221. {
  2222.   if (dest_)
  2223.      dest_->cont();
  2224. }
  2225.  
  2226. void MidiCopy::stop()
  2227. {
  2228.   if (dest_)
  2229.      dest_->stop();
  2230. }
  2231.  
  2232. void MidiCopy::activesense()
  2233. {
  2234.   if (dest_)
  2235.      dest_->activesense();
  2236. }
  2237.  
  2238. void MidiCopy::sysex(int syslen, unsigned char* sysdata)
  2239. {
  2240.   if (dest_)
  2241.      dest_->sysex(syslen, sysdata);
  2242. }
  2243.  
  2244. void MidiCopy::xgreset()
  2245. {
  2246.   if (dest_)
  2247.      dest_->xgreset();
  2248. }
  2249.  
  2250. void MidiCopy::gmreset()
  2251. {
  2252.   if (dest_)
  2253.      dest_->gmreset();
  2254. }
  2255.  
  2256. void MidiCopy::gsreset()
  2257. {
  2258.   if (dest_)
  2259.      dest_->gsreset();
  2260. }
  2261.  
  2262. void MidiCopy::gsexit()
  2263. {
  2264.   if (dest_)
  2265.      dest_->gsexit();
  2266. }
  2267.  
  2268. void MidiCopy::setoutput(MidiWrite* dest)
  2269. {
  2270.   assert(dest != NULL && dest->getf() != NULL); // need a valid MidiWrite instance
  2271.   dest_ = dest;
  2272. }
  2273.  
  2274. void MidiCopy::stopoutput()
  2275. {
  2276.   dest_ = NULL; // owner is responsible for deleting the MidiWrite object
  2277. }
  2278.  
  2279. MidiWrite* MidiCopy::getoutput()
  2280. {
  2281.   return dest_;
  2282. }
  2283.  
  2284. void MidiCopy::mapchannel(int channel, int newchannel)
  2285. {
  2286.   assert(channel >= 0 && channel < 16);
  2287.   assert(newchannel >= 0 && newchannel < 16);
  2288.   mapchannel_[channel] = newchannel;
  2289. }
  2290.  
  2291. void MidiCopy::ignorechannel(int channel)
  2292. {
  2293.   assert(channel >= 0 && channel < 16);
  2294.   mapchannel_[channel] = -1;
  2295. }
  2296.  
  2297. MidiSerial::MidiSerial(const char* filename, FILE* f, char preload)
  2298.  : MidiRead(filename, f, preload)
  2299. {
  2300.   trackpos_ = 0;
  2301.   tracktime_ = 0;
  2302.   if (runhead())
  2303.   {
  2304.     if (tracks_ < 0 || tracks_ >= 256)
  2305.       tracks_ = 0;
  2306.     else
  2307.     {
  2308.       trackpos_ = (long*)malloc(tracks_ * sizeof(long));
  2309.       trackendpos_ = (long*)malloc(tracks_ * sizeof(long));
  2310.       tracktime_= (long*)malloc(tracks_ * sizeof(long));
  2311.       trackready_ = (char*)malloc(tracks_ * sizeof(char));
  2312.       trackstatus_ = (int*)malloc(tracks_ * sizeof(int));
  2313.       if (!trackpos_ || !trackendpos_ || !tracktime_ || !trackready_ || !trackstatus_)
  2314.     clear();
  2315.     }
  2316.   }
  2317. }
  2318.  
  2319. void MidiSerial::clear()
  2320. {
  2321.   if (trackpos_)
  2322.     free(trackpos_);
  2323.   trackpos_ = NULL;
  2324.   if (tracktime_)
  2325.     free(tracktime_);
  2326.   tracktime_ = NULL;
  2327.   if (trackready_)
  2328.     free(trackready_);
  2329.   trackready_= NULL;
  2330.   if (trackstatus_)
  2331.     free(trackstatus_);
  2332.   trackstatus_= NULL;
  2333.   tracks_ = 0;
  2334. }
  2335.  
  2336. MidiSerial::~MidiSerial()
  2337. {
  2338.   clear();
  2339. }
  2340.  
  2341.  
  2342. int MidiSerial::run()
  2343. {
  2344. int saveoptions = options_;
  2345. int i;
  2346.  
  2347.   if (tracks_ == 1)
  2348.     return MidiRead::run();
  2349.  
  2350.   if (!trackpos_)
  2351.     return 0;
  2352.  
  2353.   pos_ = curpos_ = 0;
  2354.   if (!runhead())
  2355.     return 0;
  2356.    for (i = 0; i < tracks_; i++)
  2357.    {
  2358.       trackpos_[i] = 0;
  2359.       trackendpos_[i] = 0;
  2360.       tracktime_[i] = 0;
  2361.       trackready_[i] = 0;
  2362.       trackstatus_[i] = -1;
  2363.    }
  2364.  
  2365.   // get track positions and first delta and status
  2366.   options_ = OPTION_NOEVENTS;
  2367.   for (i = 0; i < tracks_; i++)
  2368.   {
  2369.     trackpos_[i] = curpos_+8;
  2370.     trackno_ = i+1;
  2371.     if (!runtrack(trackno_))
  2372.       return 0;
  2373.     trackendpos_[i] = trackpos_[i] + tracklen_;
  2374.  
  2375.     if (tracklen_ == 0)
  2376.       trackready_[i] = 1;
  2377.     else
  2378.     {
  2379.       seek(trackpos_[i]);
  2380.       tracktime_[i] = getdelta();
  2381.       if ( tracktime_[i] >= NOTREALISTIC_PAUSE )
  2382.     warning("Unrealistic large pause found");
  2383.       trackpos_[i] = curpos_;
  2384.       seek(trackendpos_[i]);
  2385.     }
  2386.   }
  2387.   options_ = saveoptions;
  2388.  
  2389.   curunit_ = 0;
  2390.   unsigned long nexttime = 0;
  2391.   while (1)
  2392.   {
  2393.     trackno_ = 0;
  2394.     for (i = 0; i < tracks_; i++)
  2395.     if (!trackready_[i])
  2396.     {
  2397.       if (trackno_ == 0 || tracktime_[i] < nexttime)
  2398.       {
  2399.     trackno_ = i+1;
  2400.     nexttime = tracktime_[i];
  2401.     if (nexttime == curunit_)
  2402.       break;
  2403.       }
  2404.     }
  2405.     if (trackno_ == 0)
  2406.       break;
  2407.  
  2408.     time(nexttime - curunit_);
  2409.     calctime(nexttime-curunit_, curms_, currest_);
  2410.  
  2411.     for (i = 0; i < tracks_; i++)
  2412.     while (!trackready_[i] && tracktime_[i] == nexttime)
  2413.     {
  2414.       trackno_ = i;
  2415.       lastcode_ = trackstatus_[i];
  2416.       seek(trackpos_[i]);
  2417.       curunit_ = nexttime;
  2418.       if (runevent(trackendpos_[i]) <= 0)
  2419.     return 0;
  2420.       if (curpos_ >= trackendpos_[i])
  2421.     trackready_[i] = 1;
  2422.       else
  2423.       {
  2424.     trackstatus_[i] = lastcode_;
  2425.     tracktime_[i] += getdelta();
  2426.     if ( tracktime_[i] >= NOTREALISTIC_PAUSE )
  2427.       warning("Unrealistic large pause found");
  2428.     trackpos_[i] = curpos_;
  2429.       }
  2430.     }
  2431.   }
  2432.  
  2433.   if (curpos_ >= filesize_)
  2434.     percent(percent_ = 100);
  2435.   endmidi();
  2436.   return 1;
  2437. }
  2438.  
  2439. void MidiSerial::track(int trackno, long length, int channel)
  2440. {
  2441. }
  2442.  
  2443. void MidiSerial::endtrack(int trackno)
  2444. {
  2445. }
  2446.